/**
 * 
 */
package t4j.concurrency;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class GreenhouseScheduler {
	private volatile boolean light = false;
	private volatile boolean water = false;
	private String thermostat = "Day";

	public synchronized String getThermostat() {
		return thermostat;
	}

	public synchronized void setThermostat(String thermostat) {
		this.thermostat = thermostat;
	}

	ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(10);

	public void schedule(Runnable event, long delay) {
//		command - 要执行的任务
//		delay - 从现在开始延迟执行的时间
//		unit - 延迟参数的时间单位 
		scheduler.schedule(event, delay, TimeUnit.MILLISECONDS);//把任务放进线程池里
	}

	public void repeat(Runnable event, long initialDelay, long period) {
//		command - 要执行的任务
//		initialDelay - 首次执行的延迟时间
//		period - 连续执行之间的周期
//		unit - initialDelay 和 period 参数的时间单位 
		scheduler.scheduleAtFixedRate(event, initialDelay, period, TimeUnit.MILLISECONDS);//把任务放进线程池里
	}

	class LightOn implements Runnable {

		@Override
		public void run() {
			System.out.println("Turning on lights");
			light = true;
		}
	}

	class LightOff implements Runnable {

		@Override
		public void run() {
			System.out.println("Turning off lights");
			light = false;
		}
	}

	class WaterOn implements Runnable {

		@Override
		public void run() {
			System.out.println("Turning greenhouse water on");
			water = true;
		}
	}

	class WaterOff implements Runnable {

		@Override
		public void run() {
			System.out.println("Turning greenhouse water off");
			water = false;
		}
	}

	//晚上恒温器
	class ThermostatNight implements Runnable {

		@Override
		public void run() {
			System.out.println("ThermostatNight to day setting");
			setThermostat("Night");
		}
	}

	////白天恒温器
	class ThermostatDay implements Runnable {

		@Override
		public void run() {
			System.out.println("ThermostatDay to day setting");
			setThermostat("Day");
		}
	}

	//电话
	class Bell implements Runnable {

		@Override
		public void run() {
			System.out.println("Bing!");
		}
	}

	//终结
	class Terminate implements Runnable {

		@Override
		public void run() {
			System.out.println("Terminating");
			scheduler.shutdownNow();//终止线程

			new Thread() {
				public void run() {
					for (DataPoint d : data)
						System.out.println(d);
				}
			}.start();
		}
	}

	//数据段
	static class DataPoint {
		final Calendar time;
		final float temperature;//温度
		final float humidity;//湿度

		public DataPoint(Calendar d, float temp, float hum) {
			time = d;
			temperature = temp;
			humidity = hum;
		}

		@Override
		public String toString() {

			return time.getTime() + String.format(" temperature: %1$.1f humidity: %2$.2f", temperature, humidity);
		}
	}

	private Calendar lastTime = Calendar.getInstance();//记录当前时间

	//初始化lastTime
	{
		lastTime.set(Calendar.MINUTE, 30);
		lastTime.set(Calendar.SECOND, 00);
	}
	
	private float lastTemp = 65.0f;
	private int tempDirection = +1;
	private float lastHumidity = 50.0f;
	private int humidityDirection = + 1;
	private Random rand = new Random(47);
	
	List<DataPoint> data = Collections.synchronizedList(new ArrayList<DataPoint>());//数据段List
	
	//数据段集合，用来定时调度记录温度和湿度
	class CollectData implements Runnable{

		@Override
		public void run() {
			System.out.println("Collecting data");
			
			synchronized (GreenhouseScheduler.this) {
				lastTime.set(Calendar.MINUTE, lastTime.get(Calendar.MINUTE)+30);//每次在最后时间+30分钟
				
				if(rand.nextInt(5) == 4)
					tempDirection = -tempDirection;
				
				lastTemp = lastTemp + tempDirection * (1.0f + rand.nextFloat());
				
				if(rand.nextInt(5) == 4)
					humidityDirection = -humidityDirection;
				
				lastHumidity = lastHumidity + humidityDirection * rand.nextFloat();
				
				data.add(new DataPoint((Calendar) lastTime.clone(), lastTemp, lastHumidity));//加一个数据点
			}
		}	
	}
	
	public static void main(String[] args) {
		GreenhouseScheduler gh = new GreenhouseScheduler();
		
		gh.schedule(gh.new Terminate(), 5000);
		
		gh.repeat(gh.new Bell(), 0, 1000);
		gh.repeat(gh.new ThermostatNight(), 0, 2000);///表示启动延迟0个单位开始执行这个线程，然后每隔2000毫秒执行一次
		gh.repeat(gh.new LightOn(), 0, 200);
		gh.repeat(gh.new LightOff(), 0, 400);
		gh.repeat(gh.new WaterOn(), 0, 600);
		gh.repeat(gh.new WaterOff(), 0, 800);
		gh.repeat(gh.new ThermostatDay(), 0, 1400);
		gh.repeat(gh.new CollectData(), 500, 500);//每500毫秒记录一下数据段
	}

}
